home *** CD-ROM | disk | FTP | other *** search
/ isnet Internet / Isnet Internet CD.iso / prog / hiz / 09 / 09.exe / adynware.exe / perl / lib / site / Set / IntegerRange.pm < prev   
Encoding:
Perl POD Document  |  1999-12-28  |  34.1 KB  |  1,509 lines

  1.  
  2.  
  3. package Set::IntegerRange;
  4.  
  5. use strict;
  6. use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
  7.  
  8. require Exporter;
  9.  
  10. @ISA = qw(Exporter);
  11.  
  12. @EXPORT = qw();
  13.  
  14. @EXPORT_OK = qw();
  15.  
  16. $VERSION = '4.2';
  17.  
  18. use Carp;
  19.  
  20. use Bit::Vector;
  21.  
  22. use overload
  23.       '""' => '_string',
  24.      'neg' => '_complement',
  25.        '~' => '_complement',
  26.     'bool' => '_boolean',
  27.        '!' => '_not_boolean',
  28.      'abs' => '_norm',
  29.        '+' => '_union',
  30.        '|' => '_union',                  # alternative for '+'
  31.        '-' => '_difference',
  32.        '*' => '_intersection',
  33.        '&' => '_intersection',           # alternative for '*'
  34.        '^' => '_exclusive_or',
  35.       '+=' => '_assign_union',
  36.       '|=' => '_assign_union',           # alternative for '+='
  37.       '-=' => '_assign_difference',
  38.       '*=' => '_assign_intersection',
  39.       '&=' => '_assign_intersection',    # alternative for '*='
  40.       '^=' => '_assign_exclusive_or',
  41.       '==' => '_equal',
  42.       '!=' => '_not_equal',
  43.        '<' => '_true_sub_set',
  44.       '<=' => '_sub_set',
  45.        '>' => '_true_super_set',
  46.       '>=' => '_super_set',
  47.      'cmp' => '_compare',                # also enables lt, le, gt, ge, eq, ne
  48.        '=' => '_clone',
  49. 'fallback' =>   undef;
  50.  
  51. sub new
  52. {
  53.     croak "Usage: \$set = Set::IntegerRange->new(\$lower,\$upper);"
  54.       if (@_ != 3);
  55.  
  56.     my $proto = shift;
  57.     my $class = ref($proto) || $proto || 'Set::IntegerRange';
  58.     my $lower = shift;
  59.     my $upper = shift;
  60.     my $object;
  61.     my $set;
  62.  
  63.     if ($lower <= $upper)
  64.     {
  65.         $set = Bit::Vector->new($upper-$lower+1);
  66.         if ((defined $set) && ref($set) && (${$set} != 0))
  67.         {
  68.             $object = [ $set, $lower, $upper ];
  69.             bless($object, $class);
  70.             return($object);
  71.         }
  72.         else
  73.         {
  74.             croak
  75.   "Set::IntegerRange::new(): unable to create new 'Set::IntegerRange' object";
  76.         }
  77.     }
  78.     else
  79.     {
  80.         croak
  81.   "Set::IntegerRange::new(): lower > upper boundary";
  82.     }
  83. }
  84.  
  85. sub Resize
  86. {
  87.     croak "Usage: \$set->Resize(\$lower,\$upper);"
  88.       if (@_ != 3);
  89.  
  90.     my($object,$new_lower,$new_upper) = @_;
  91.     my($old_lower,$old_upper) = ($object->[1],$object->[2]);
  92.     my($diff);
  93.  
  94.     if ($new_lower <= $new_upper)
  95.     {
  96.         $diff = $new_lower - $old_lower;
  97.         if ($diff == 0)
  98.         {
  99.             $object->[0]->Resize($new_upper-$new_lower+1);
  100.         }
  101.         else
  102.         {
  103.             if ($diff > 0)
  104.             {
  105.                 $object->[0]->Move_Right($diff);
  106.                 $object->[0]->Resize($new_upper-$new_lower+1);
  107.             }
  108.             else
  109.             {
  110.                 $object->[0]->Resize($new_upper-$new_lower+1);
  111.                 $object->[0]->Move_Left(-$diff);
  112.             }
  113.         }
  114.         ($object->[1],$object->[2]) = ($new_lower,$new_upper);
  115.     }
  116.     else
  117.     {
  118.         croak "Set::IntegerRange::Resize(): lower > upper boundary";
  119.     }
  120. }
  121.  
  122. sub Size
  123. {
  124.     croak "Usage: (\$lower,\$upper) = \$set->Size();"
  125.       if (@_ != 1);
  126.  
  127.     my($object) = @_;
  128.  
  129.     return( $object->[1], $object->[2] );
  130. }
  131.  
  132. sub BitVector
  133. {
  134.     croak "Usage: \$set->BitVector->any_Bit_Vector_method();"
  135.       if (@_ != 1);
  136.  
  137.     my($object) = @_;
  138.  
  139.     return( $object->[0] );
  140. }
  141.  
  142. sub Empty
  143. {
  144.     croak "Usage: \$set->Empty();"
  145.       if (@_ != 1);
  146.  
  147.     my($object) = @_;
  148.  
  149.     $object->[0]->Empty();
  150. }
  151.  
  152. sub Fill
  153. {
  154.     croak "Usage: \$set->Fill();"
  155.       if (@_ != 1);
  156.  
  157.     my($object) = @_;
  158.  
  159.     $object->[0]->Fill();
  160. }
  161.  
  162. sub Flip
  163. {
  164.     croak "Usage: \$set->Flip();"
  165.       if (@_ != 1);
  166.  
  167.     my($object) = @_;
  168.  
  169.     $object->[0]->Flip();
  170. }
  171.  
  172. sub Interval_Empty
  173. {
  174.     croak "Usage: \$set->Interval_Empty(\$min,\$max);"
  175.       if (@_ != 3);
  176.  
  177.     my($object,$min,$max) = @_;
  178.     my($lower,$upper) = ($object->[1],$object->[2]);
  179.  
  180.     croak "Set::IntegerRange::Interval_Empty(): minimum index out of range"
  181.       if (($min < $lower) || ($min > $upper));
  182.  
  183.     croak "Set::IntegerRange::Interval_Empty(): maximum index out of range"
  184.       if (($max < $lower) || ($max > $upper));
  185.  
  186.     croak "Set::IntegerRange::Interval_Empty(): minimum > maximum index"
  187.       if ($min > $max);
  188.  
  189.     $object->[0]->Interval_Empty($min-$lower,$max-$lower);
  190. }
  191.  
  192. sub Interval_Fill
  193. {
  194.     croak "Usage: \$set->Interval_Fill(\$min,\$max);"
  195.       if (@_ != 3);
  196.  
  197.     my($object,$min,$max) = @_;
  198.     my($lower,$upper) = ($object->[1],$object->[2]);
  199.  
  200.     croak "Set::IntegerRange::Interval_Fill(): minimum index out of range"
  201.       if (($min < $lower) || ($min > $upper));
  202.  
  203.     croak "Set::IntegerRange::Interval_Fill(): maximum index out of range"
  204.       if (($max < $lower) || ($max > $upper));
  205.  
  206.     croak "Set::IntegerRange::Interval_Fill(): minimum > maximum index"
  207.       if ($min > $max);
  208.  
  209.     $object->[0]->Interval_Fill($min-$lower,$max-$lower);
  210. }
  211.  
  212. sub Interval_Flip
  213. {
  214.     croak "Usage: \$set->Interval_Flip(\$min,\$max);"
  215.       if (@_ != 3);
  216.  
  217.     my($object,$min,$max) = @_;
  218.     my($lower,$upper) = ($object->[1],$object->[2]);
  219.  
  220.     croak "Set::IntegerRange::Interval_Flip(): minimum index out of range"
  221.       if (($min < $lower) || ($min > $upper));
  222.  
  223.     croak "Set::IntegerRange::Interval_Flip(): maximum index out of range"
  224.       if (($max < $lower) || ($max > $upper));
  225.  
  226.     croak "Set::IntegerRange::Interval_Flip(): minimum > maximum index"
  227.       if ($min > $max);
  228.  
  229.     $object->[0]->Interval_Flip($min-$lower,$max-$lower);
  230. }
  231.  
  232. sub Interval_Scan_inc
  233. {
  234.     croak "Usage: (\$min,\$max) = \$set->Interval_Scan_inc(\$start);"
  235.       if (@_ != 2);
  236.  
  237.     my($object,$start) = @_;
  238.     my($lower,$upper) = ($object->[1],$object->[2]);
  239.     my($min,$max);
  240.  
  241.     croak "Set::IntegerRange::Interval_Scan_inc(): start index out of range"
  242.       if (($start < $lower) || ($start > $upper));
  243.  
  244.     if (($min,$max) = $object->[0]->Interval_Scan_inc($start-$lower))
  245.     {
  246.         $min += $lower;
  247.         $max += $lower;
  248.         return($min,$max);
  249.     }
  250.     else
  251.     {
  252.         return();
  253.     }
  254. }
  255.  
  256. sub Interval_Scan_dec
  257. {
  258.     croak "Usage: (\$min,\$max) = \$set->Interval_Scan_dec(\$start);"
  259.       if (@_ != 2);
  260.  
  261.     my($object,$start) = @_;
  262.     my($lower,$upper) = ($object->[1],$object->[2]);
  263.     my($min,$max);
  264.  
  265.     croak "Set::IntegerRange::Interval_Scan_dec(): start index out of range"
  266.       if (($start < $lower) || ($start > $upper));
  267.  
  268.     if (($min,$max) = $object->[0]->Interval_Scan_dec($start-$lower))
  269.     {
  270.         $min += $lower;
  271.         $max += $lower;
  272.         return($min,$max);
  273.     }
  274.     else
  275.     {
  276.         return();
  277.     }
  278. }
  279.  
  280. sub Bit_Off
  281. {
  282.     croak "Usage: \$set->Bit_Off(\$index);"
  283.       if (@_ != 2);
  284.  
  285.     my($object,$index) = @_;
  286.     my($lower,$upper) = ($object->[1],$object->[2]);
  287.  
  288.     if (($index >= $lower) && ($index <= $upper))
  289.     {
  290.         $object->[0]->Bit_Off($index-$lower);
  291.     }
  292.     else
  293.     {
  294.         croak "Set::IntegerRange::Bit_Off(): index out of range";
  295.     }
  296. }
  297.  
  298. sub Bit_On
  299. {
  300.     croak "Usage: \$set->Bit_On(\$index);"
  301.       if (@_ != 2);
  302.  
  303.     my($object,$index) = @_;
  304.     my($lower,$upper) = ($object->[1],$object->[2]);
  305.  
  306.     if (($index >= $lower) && ($index <= $upper))
  307.     {
  308.         $object->[0]->Bit_On($index-$lower);
  309.     }
  310.     else
  311.     {
  312.         croak "Set::IntegerRange::Bit_On(): index out of range";
  313.     }
  314. }
  315.  
  316. sub bit_flip
  317. {
  318.     croak "Usage: if (\$set->bit_flip(\$index))"
  319.       if (@_ != 2);
  320.  
  321.     my($object,$index) = @_;
  322.     my($lower,$upper) = ($object->[1],$object->[2]);
  323.  
  324.     if (($index >= $lower) && ($index <= $upper))
  325.     {
  326.         return( $object->[0]->bit_flip($index-$lower) );
  327.     }
  328.     else
  329.     {
  330.         croak "Set::IntegerRange::bit_flip(): index out of range";
  331.     }
  332. }
  333.  
  334. sub bit_test
  335. {
  336.     croak "Usage: if (\$set->bit_test(\$index))"
  337.       if (@_ != 2);
  338.  
  339.     my($object,$index) = @_;
  340.     my($lower,$upper) = ($object->[1],$object->[2]);
  341.  
  342.     if (($index >= $lower) && ($index <= $upper))
  343.     {
  344.         return( $object->[0]->bit_test($index-$lower) );
  345.     }
  346.     else
  347.     {
  348.         croak "Set::IntegerRange::bit_test(): index out of range";
  349.     }
  350. }
  351.  
  352. sub Norm
  353. {
  354.     croak "Usage: \$norm = \$set->Norm();"
  355.       if (@_ != 1);
  356.  
  357.     my($object) = @_;
  358.  
  359.     return( $object->[0]->Norm() );
  360. }
  361.  
  362. sub Min
  363. {
  364.     croak "Usage: \$min = \$set->Min();"
  365.       if (@_ != 1);
  366.  
  367.     my($object) = @_;
  368.     my($lower,$upper) = ($object->[1],$object->[2]);
  369.     my($result);
  370.  
  371.     $result = $object->[0]->Min();
  372.     return( (($result >= 0) && ($result <= ($upper-$lower))) ?
  373.             ($result+$lower) : $result );
  374. }
  375.  
  376. sub Max
  377. {
  378.     croak "Usage: \$max = \$set->Max();"
  379.       if (@_ != 1);
  380.  
  381.     my($object) = @_;
  382.     my($lower,$upper) = ($object->[1],$object->[2]);
  383.     my($result);
  384.  
  385.     $result = $object->[0]->Max();
  386.     return( (($result >= 0) && ($result <= ($upper-$lower))) ?
  387.             ($result+$lower) : $result );
  388. }
  389.  
  390. sub Union
  391. {
  392.     croak "Usage: \$set1->Union(\$set2,\$set3);"
  393.       if (@_ != 3);
  394.  
  395.     my($set1,$set2,$set3) = @_;
  396.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  397.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  398.     my($lower3,$upper3) = ($set3->[1],$set3->[2]);
  399.  
  400.     if (($lower1 == $lower2) && ($lower1 == $lower3) &&
  401.         ($upper1 == $upper2) && ($upper1 == $upper3))
  402.     {
  403.         $set1->[0]->Union($set2->[0],$set3->[0]);
  404.     }
  405.     else
  406.     {
  407.         croak "Set::IntegerRange::Union(): set size mismatch";
  408.     }
  409. }
  410.  
  411. sub Intersection
  412. {
  413.     croak "Usage: \$set1->Intersection(\$set2,\$set3);"
  414.       if (@_ != 3);
  415.  
  416.     my($set1,$set2,$set3) = @_;
  417.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  418.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  419.     my($lower3,$upper3) = ($set3->[1],$set3->[2]);
  420.  
  421.     if (($lower1 == $lower2) && ($lower1 == $lower3) &&
  422.         ($upper1 == $upper2) && ($upper1 == $upper3))
  423.     {
  424.         $set1->[0]->Intersection($set2->[0],$set3->[0]);
  425.     }
  426.     else
  427.     {
  428.         croak "Set::IntegerRange::Intersection(): set size mismatch";
  429.     }
  430. }
  431.  
  432. sub Difference
  433. {
  434.     croak "Usage: \$set1->Difference(\$set2,\$set3);"
  435.       if (@_ != 3);
  436.  
  437.     my($set1,$set2,$set3) = @_;
  438.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  439.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  440.     my($lower3,$upper3) = ($set3->[1],$set3->[2]);
  441.  
  442.     if (($lower1 == $lower2) && ($lower1 == $lower3) &&
  443.         ($upper1 == $upper2) && ($upper1 == $upper3))
  444.     {
  445.         $set1->[0]->Difference($set2->[0],$set3->[0]);
  446.     }
  447.     else
  448.     {
  449.         croak "Set::IntegerRange::Difference(): set size mismatch";
  450.     }
  451. }
  452.  
  453. sub ExclusiveOr
  454. {
  455.     croak "Usage: \$set1->ExclusiveOr(\$set2,\$set3);"
  456.       if (@_ != 3);
  457.  
  458.     my($set1,$set2,$set3) = @_;
  459.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  460.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  461.     my($lower3,$upper3) = ($set3->[1],$set3->[2]);
  462.  
  463.     if (($lower1 == $lower2) && ($lower1 == $lower3) &&
  464.         ($upper1 == $upper2) && ($upper1 == $upper3))
  465.     {
  466.         $set1->[0]->ExclusiveOr($set2->[0],$set3->[0]);
  467.     }
  468.     else
  469.     {
  470.         croak "Set::IntegerRange::ExclusiveOr(): set size mismatch";
  471.     }
  472. }
  473.  
  474. sub Complement
  475. {
  476.     croak "Usage: \$set1->Complement(\$set2);"
  477.       if (@_ != 2);
  478.  
  479.     my($set1,$set2) = @_;
  480.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  481.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  482.  
  483.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  484.     {
  485.         $set1->[0]->Complement($set2->[0]);
  486.     }
  487.     else
  488.     {
  489.         croak "Set::IntegerRange::Complement(): set size mismatch";
  490.     }
  491. }
  492.  
  493. sub is_empty
  494. {
  495.     croak "Usage: if (\$set->is_empty())"
  496.       if (@_ != 1);
  497.  
  498.     my($object) = @_;
  499.  
  500.     return( $object->[0]->is_empty() );
  501. }
  502.  
  503. sub is_full
  504. {
  505.     croak "Usage: if (\$set->is_full())"
  506.       if (@_ != 1);
  507.  
  508.     my($object) = @_;
  509.  
  510.     return( $object->[0]->is_full() );
  511. }
  512.  
  513. sub equal
  514. {
  515.     croak "Usage: if (\$set1->equal(\$set2))"
  516.       if (@_ != 2);
  517.  
  518.     my($set1,$set2) = @_;
  519.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  520.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  521.  
  522.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  523.     {
  524.         return( $set1->[0]->equal($set2->[0]) );
  525.     }
  526.     else
  527.     {
  528.         croak "Set::IntegerRange::equal(): set size mismatch";
  529.     }
  530. }
  531.  
  532. sub subset
  533. {
  534.     croak "Usage: if (\$set1->subset(\$set2))"
  535.       if (@_ != 2);
  536.  
  537.     my($set1,$set2) = @_;
  538.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  539.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  540.  
  541.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  542.     {
  543.         return( $set1->[0]->subset($set2->[0]) );
  544.     }
  545.     else
  546.     {
  547.         croak "Set::IntegerRange::subset(): set size mismatch";
  548.     }
  549. }
  550.  
  551. sub lexorder
  552. {
  553.     croak "Usage: if (\$set1->lexorder(\$set2))"
  554.       if (@_ != 2);
  555.  
  556.     my($set1,$set2) = @_;
  557.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  558.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  559.  
  560.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  561.     {
  562.         return( $set1->[0]->lexorder($set2->[0]) );
  563.     }
  564.     else
  565.     {
  566.         croak "Set::IntegerRange::lexorder(): set size mismatch";
  567.     }
  568. }
  569.  
  570. sub Compare
  571. {
  572.     croak "Usage: \$cmp = \$set1->Compare(\$set2);"
  573.       if (@_ != 2);
  574.  
  575.     my($set1,$set2) = @_;
  576.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  577.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  578.  
  579.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  580.     {
  581.         return( $set1->[0]->Compare($set2->[0]) );
  582.     }
  583.     else
  584.     {
  585.         croak "Set::IntegerRange::Compare(): set size mismatch";
  586.     }
  587. }
  588.  
  589. sub Copy
  590. {
  591.     croak "Usage: \$set1->Copy(\$set2);"
  592.       if (@_ != 2);
  593.  
  594.     my($set1,$set2) = @_;
  595.     my($lower1,$upper1) = ($set1->[1],$set1->[2]);
  596.     my($lower2,$upper2) = ($set2->[1],$set2->[2]);
  597.  
  598.     if (($lower1 == $lower2) && ($upper1 == $upper2))
  599.     {
  600.         $set1->[0]->Copy($set2->[0]);
  601.     }
  602.     else
  603.     {
  604.         croak "Set::IntegerRange::Copy(): set size mismatch";
  605.     }
  606. }
  607.  
  608. sub Shadow
  609. {
  610.     croak "Usage: \$other_set = \$some_set->Shadow();"
  611.       if (@_ != 1);
  612.  
  613.     my($object) = @_;
  614.     my($result);
  615.  
  616.     $result = $object->new($object->[1],$object->[2]);
  617.     return($result);
  618. }
  619.  
  620. sub Clone
  621. {
  622.     croak "Usage: \$twin_set = \$some_set->Clone();"
  623.       if (@_ != 1);
  624.  
  625.     my($object) = @_;
  626.     my($result);
  627.  
  628.     $result = $object->new($object->[1],$object->[2]);
  629.     $result->Copy($object);
  630.     return($result);
  631. }
  632.  
  633. sub Delete
  634. {
  635.     Bit_Off(@_);
  636. }
  637.  
  638. sub Insert
  639. {
  640.     Bit_On(@_);
  641. }
  642.  
  643. sub flip
  644. {
  645.     return( bit_flip(@_) );
  646. }
  647.  
  648. sub contains
  649. {
  650.     return( bit_test(@_) );
  651. }
  652.  
  653. sub in
  654. {
  655.     return( bit_test(@_) );
  656. }
  657.  
  658. sub inclusion
  659. {
  660.     return( subset(@_) );
  661. }
  662.  
  663. sub Empty_Interval
  664. {
  665.     Interval_Empty(@_);
  666. }
  667.  
  668. sub Fill_Interval
  669. {
  670.     Interval_Fill(@_);
  671. }
  672.  
  673. sub Flip_Interval
  674. {
  675.     Interval_Flip(@_);
  676. }
  677.  
  678. sub to_ASCII
  679. {
  680.     croak "Usage: \$string = \$set->to_ASCII();"
  681.       if (@_ != 1);
  682.  
  683.     my($object) = @_;
  684.     my($lower) = $object->[1];
  685.     my($start,$string);
  686.     my($min,$max);
  687.  
  688.     $start = 0;
  689.     $string = '';
  690.     while (($start < $object->[0]->Size()) &&
  691.         (($min,$max) = $object->[0]->Interval_Scan_inc($start)))
  692.     {
  693.         $start = $max + 2;
  694.         $min += $lower;
  695.         $max += $lower;
  696.         if    ($min == $max)   { $string .= "${min},"; }
  697.         elsif ($min == $max-1) { $string .= "${min},${max},"; }
  698.         else                   { $string .= "${min}..${max},"; }
  699.     }
  700.     $string =~ s/,$//;
  701.     return($string);
  702. }
  703.  
  704. sub from_ASCII
  705. {
  706.     croak "Usage: \$set->from_ASCII(\$string);"
  707.       if (@_ != 2);
  708.  
  709.     my($object,$string) = @_;
  710.     my($lower,$upper) = ($object->[1],$object->[2]);
  711.     my(@intervals,$interval);
  712.     my($min,$max);
  713.  
  714.     croak "Set::IntegerRange::from_ASCII(): syntax error in input string"
  715.       unless ($string =~ /^ (?: [+-]? \d+ (?: \.\. [+-]? \d+ )? )
  716.                       (?: , (?: [+-]? \d+ (?: \.\. [+-]? \d+ )? ) )* $/x);
  717.  
  718.     $object->[0]->Empty();
  719.  
  720.     @intervals = split(/,/, $string);
  721.  
  722.     foreach $interval (@intervals)
  723.     {
  724.         if ($interval =~ /\.\./)
  725.         {
  726.             ($min,$max) = split(/\.\./, $interval);
  727.  
  728.             croak "Set::IntegerRange::from_ASCII(): minimum index out of range"
  729.               if (($min < $lower) || ($min > $upper));
  730.  
  731.             croak "Set::IntegerRange::from_ASCII(): maximum index out of range"
  732.               if (($max < $lower) || ($max > $upper));
  733.  
  734.             croak "Set::IntegerRange::from_ASCII(): minimum > maximum index"
  735.               if ($min > $max);
  736.  
  737.             $min -= $lower;
  738.             $max -= $lower;
  739.  
  740.             $object->[0]->Interval_Fill($min,$max);
  741.         }
  742.         else
  743.         {
  744.             croak "Set::IntegerRange::from_ASCII(): index out of range"
  745.               if (($interval < $lower) || ($interval > $upper));
  746.  
  747.             $interval -= $lower;
  748.  
  749.             $object->[0]->Bit_On($interval);
  750.         }
  751.     }
  752. }
  753.  
  754. sub to_String
  755. {
  756.     croak "Usage: \$string = \$set->to_String();"
  757.       if (@_ != 1);
  758.  
  759.     my($object) = @_;
  760.  
  761.     return( $object->[0]->to_String() );
  762. }
  763.  
  764. sub from_String
  765. {
  766.     croak "Usage: \$set->from_String(\$string);"
  767.       if (@_ != 2);
  768.  
  769.     my($object,$string) = @_;
  770.  
  771.     unless ($object->[0]->from_string($string))
  772.     {
  773.         croak "Set::IntegerRange::from_String(): syntax error in input string";
  774.     }
  775. }
  776.  
  777.  
  778. sub _string
  779. {
  780.     my($object,$argument,$flag) = @_;
  781.  
  782.     return( $object->to_ASCII() );
  783. }
  784.  
  785. sub _complement
  786. {
  787.     my($object,$argument,$flag) = @_;
  788.     my($result);
  789.  
  790.     $result = $object->new($object->[1],$object->[2]);
  791.     $result->Complement($object);
  792.     return($result);
  793. }
  794.  
  795. sub _boolean
  796. {
  797.     my($object,$argument,$flag) = @_;
  798.  
  799.     return( ! $object->is_empty() );
  800. }
  801.  
  802. sub _not_boolean
  803. {
  804.     my($object,$argument,$flag) = @_;
  805.  
  806.     return( $object->is_empty() );
  807. }
  808.  
  809. sub _norm
  810. {
  811.     my($object,$argument,$flag) = @_;
  812.  
  813.     return( $object->Norm() );
  814. }
  815.  
  816. sub _union
  817. {
  818.     my($object,$argument,$flag) = @_;
  819.     my($name) = "'+'"; #&_trace($name,$object,$argument,$flag);
  820.     my($result);
  821.  
  822.     if ((defined $argument) && ref($argument) &&
  823.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  824.     {
  825.         if (defined $flag)
  826.         {
  827.             $result = $object->new($object->[1],$object->[2]);
  828.             $result->Union($object,$argument);
  829.             return($result);
  830.         }
  831.         else
  832.         {
  833.             $object->Union($object,$argument);
  834.             return($object);
  835.         }
  836.     }
  837.     elsif ((defined $argument) && !(ref($argument)))
  838.     {
  839.         if (defined $flag)
  840.         {
  841.             $result = $object->new($object->[1],$object->[2]);
  842.             $result->Copy($object);
  843.             $result->Bit_On($argument);
  844.             return($result);
  845.         }
  846.         else
  847.         {
  848.             $object->Bit_On($argument);
  849.             return($object);
  850.         }
  851.     }
  852.     else
  853.     {
  854.         croak "Set::IntegerRange $name: wrong argument type";
  855.     }
  856. }
  857.  
  858. sub _difference
  859. {
  860.     my($object,$argument,$flag) = @_;
  861.     my($name) = "'-'"; #&_trace($name,$object,$argument,$flag);
  862.     my($result);
  863.  
  864.     if ((defined $argument) && ref($argument) &&
  865.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  866.     {
  867.         if (defined $flag)
  868.         {
  869.             $result = $object->new($object->[1],$object->[2]);
  870.             if ($flag) { $result->Difference($argument,$object); }
  871.             else       { $result->Difference($object,$argument); }
  872.             return($result);
  873.         }
  874.         else
  875.         {
  876.             $object->Difference($object,$argument);
  877.             return($object);
  878.         }
  879.     }
  880.     elsif ((defined $argument) && !(ref($argument)))
  881.     {
  882.         if (defined $flag)
  883.         {
  884.             $result = $object->new($object->[1],$object->[2]);
  885.             if ($flag)
  886.             {
  887.                 unless ($object->bit_test($argument))
  888.                 { $result->Bit_On($argument); }
  889.             }
  890.             else
  891.             {
  892.                 $result->Copy($object);
  893.                 $result->Bit_Off($argument);
  894.             }
  895.             return($result);
  896.         }
  897.         else
  898.         {
  899.             $object->Bit_Off($argument);
  900.             return($object);
  901.         }
  902.     }
  903.     else
  904.     {
  905.         croak "Set::IntegerRange $name: wrong argument type";
  906.     }
  907. }
  908.  
  909. sub _intersection
  910. {
  911.     my($object,$argument,$flag) = @_;
  912.     my($name) = "'*'"; #&_trace($name,$object,$argument,$flag);
  913.     my($result);
  914.  
  915.     if ((defined $argument) && ref($argument) &&
  916.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  917.     {
  918.         if (defined $flag)
  919.         {
  920.             $result = $object->new($object->[1],$object->[2]);
  921.             $result->Intersection($object,$argument);
  922.             return($result);
  923.         }
  924.         else
  925.         {
  926.             $object->Intersection($object,$argument);
  927.             return($object);
  928.         }
  929.     }
  930.     elsif ((defined $argument) && !(ref($argument)))
  931.     {
  932.         if (defined $flag)
  933.         {
  934.             $result = $object->new($object->[1],$object->[2]);
  935.             if ($object->bit_test($argument))
  936.             { $result->Bit_On($argument); }
  937.             return($result);
  938.         }
  939.         else
  940.         {
  941.             $flag = $object->bit_test($argument);
  942.             $object->Empty();
  943.             if ($flag) { $object->Bit_On($argument); }
  944.             return($object);
  945.         }
  946.     }
  947.     else
  948.     {
  949.         croak "Set::IntegerRange $name: wrong argument type";
  950.     }
  951. }
  952.  
  953. sub _exclusive_or
  954. {
  955.     my($object,$argument,$flag) = @_;
  956.     my($name) = "'^'"; #&_trace($name,$object,$argument,$flag);
  957.     my($result);
  958.  
  959.     if ((defined $argument) && ref($argument) &&
  960.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  961.     {
  962.         if (defined $flag)
  963.         {
  964.             $result = $object->new($object->[1],$object->[2]);
  965.             $result->ExclusiveOr($object,$argument);
  966.             return($result);
  967.         }
  968.         else
  969.         {
  970.             $object->ExclusiveOr($object,$argument);
  971.             return($object);
  972.         }
  973.     }
  974.     elsif ((defined $argument) && !(ref($argument)))
  975.     {
  976.         if (defined $flag)
  977.         {
  978.             $result = $object->new($object->[1],$object->[2]);
  979.             $result->Copy($object);
  980.             $result->bit_flip($argument);
  981.             return($result);
  982.         }
  983.         else
  984.         {
  985.             $object->bit_flip($argument);
  986.             return($object);
  987.         }
  988.     }
  989.     else
  990.     {
  991.         croak "Set::IntegerRange $name: wrong argument type";
  992.     }
  993. }
  994.  
  995. sub _assign_union
  996. {
  997.     my($object,$argument,$flag) = @_;
  998.  
  999.     return( &_union($object,$argument,undef) );
  1000. }
  1001.  
  1002. sub _assign_difference
  1003. {
  1004.     my($object,$argument,$flag) = @_;
  1005.  
  1006.     return( &_difference($object,$argument,undef) );
  1007. }
  1008.  
  1009. sub _assign_intersection
  1010. {
  1011.     my($object,$argument,$flag) = @_;
  1012.  
  1013.     return( &_intersection($object,$argument,undef) );
  1014. }
  1015.  
  1016. sub _assign_exclusive_or
  1017. {
  1018.     my($object,$argument,$flag) = @_;
  1019.  
  1020.     return( &_exclusive_or($object,$argument,undef) );
  1021. }
  1022.  
  1023. sub _equal
  1024. {
  1025.     my($object,$argument,$flag) = @_;
  1026.     my($name) = "'=='"; #&_trace($name,$object,$argument,$flag);
  1027.     my($result);
  1028.  
  1029.     if ((defined $argument) && ref($argument) &&
  1030.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1031.     {
  1032.         $result = $argument;
  1033.     }
  1034.     elsif ((defined $argument) && !(ref($argument)))
  1035.     {
  1036.         $result = $object->new($object->[1],$object->[2]);
  1037.         $result->Bit_On($argument);
  1038.     }
  1039.     else
  1040.     {
  1041.         croak "Set::IntegerRange $name: wrong argument type";
  1042.     }
  1043.     return( $object->equal($result) );
  1044. }
  1045.  
  1046. sub _not_equal
  1047. {
  1048.     my($object,$argument,$flag) = @_;
  1049.     my($name) = "'!='"; #&_trace($name,$object,$argument,$flag);
  1050.     my($result);
  1051.  
  1052.     if ((defined $argument) && ref($argument) &&
  1053.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1054.     {
  1055.         $result = $argument;
  1056.     }
  1057.     elsif ((defined $argument) && !(ref($argument)))
  1058.     {
  1059.         $result = $object->new($object->[1],$object->[2]);
  1060.         $result->Bit_On($argument);
  1061.     }
  1062.     else
  1063.     {
  1064.         croak "Set::IntegerRange $name: wrong argument type";
  1065.     }
  1066.     return( !($object->equal($result)) );
  1067. }
  1068.  
  1069. sub _true_sub_set
  1070. {
  1071.     my($object,$argument,$flag) = @_;
  1072.     my($name) = "'<'"; #&_trace($name,$object,$argument,$flag);
  1073.     my($result);
  1074.  
  1075.     if ((defined $argument) && ref($argument) &&
  1076.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1077.     {
  1078.         $result = $argument;
  1079.     }
  1080.     elsif ((defined $argument) && !(ref($argument)))
  1081.     {
  1082.         $result = $object->new($object->[1],$object->[2]);
  1083.         $result->Bit_On($argument);
  1084.     }
  1085.     else
  1086.     {
  1087.         croak "Set::IntegerRange $name: wrong argument type";
  1088.     }
  1089.     if ((defined $flag) && $flag)
  1090.     {
  1091.         return( !($result->equal($object)) &&
  1092.                  ($result->subset($object)) );
  1093.     }
  1094.     else
  1095.     {
  1096.         return( !($object->equal($result)) &&
  1097.                  ($object->subset($result)) );
  1098.     }
  1099. }
  1100.  
  1101. sub _sub_set
  1102. {
  1103.     my($object,$argument,$flag) = @_;
  1104.     my($name) = "'<='"; #&_trace($name,$object,$argument,$flag);
  1105.     my($result);
  1106.  
  1107.     if ((defined $argument) && ref($argument) &&
  1108.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1109.     {
  1110.         $result = $argument;
  1111.     }
  1112.     elsif ((defined $argument) && !(ref($argument)))
  1113.     {
  1114.         $result = $object->new($object->[1],$object->[2]);
  1115.         $result->Bit_On($argument);
  1116.     }
  1117.     else
  1118.     {
  1119.         croak "Set::IntegerRange $name: wrong argument type";
  1120.     }
  1121.     if ((defined $flag) && $flag)
  1122.     {
  1123.         return( $result->subset($object) );
  1124.     }
  1125.     else
  1126.     {
  1127.         return( $object->subset($result) );
  1128.     }
  1129. }
  1130.  
  1131. sub _true_super_set
  1132. {
  1133.     my($object,$argument,$flag) = @_;
  1134.     my($name) = "'>'"; #&_trace($name,$object,$argument,$flag);
  1135.     my($result);
  1136.  
  1137.     if ((defined $argument) && ref($argument) &&
  1138.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1139.     {
  1140.         $result = $argument;
  1141.     }
  1142.     elsif ((defined $argument) && !(ref($argument)))
  1143.     {
  1144.         $result = $object->new($object->[1],$object->[2]);
  1145.         $result->Bit_On($argument);
  1146.     }
  1147.     else
  1148.     {
  1149.         croak "Set::IntegerRange $name: wrong argument type";
  1150.     }
  1151.     if ((defined $flag) && $flag)
  1152.     {
  1153.         return( !($object->equal($result)) &&
  1154.                  ($object->subset($result)) );
  1155.     }
  1156.     else
  1157.     {
  1158.         return( !($result->equal($object)) &&
  1159.                  ($result->subset($object)) );
  1160.     }
  1161. }
  1162.  
  1163. sub _super_set
  1164. {
  1165.     my($object,$argument,$flag) = @_;
  1166.     my($name) = "'>='"; #&_trace($name,$object,$argument,$flag);
  1167.     my($result);
  1168.  
  1169.     if ((defined $argument) && ref($argument) &&
  1170.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1171.     {
  1172.         $result = $argument;
  1173.     }
  1174.     elsif ((defined $argument) && !(ref($argument)))
  1175.     {
  1176.         $result = $object->new($object->[1],$object->[2]);
  1177.         $result->Bit_On($argument);
  1178.     }
  1179.     else
  1180.     {
  1181.         croak "Set::IntegerRange $name: wrong argument type";
  1182.     }
  1183.     if ((defined $flag) && $flag)
  1184.     {
  1185.         return( $object->subset($result) );
  1186.     }
  1187.     else
  1188.     {
  1189.         return( $result->subset($object) );
  1190.     }
  1191. }
  1192.  
  1193. sub _compare
  1194. {
  1195.     my($object,$argument,$flag) = @_;
  1196.     my($name) = "cmp"; #&_trace($name,$object,$argument,$flag);
  1197.     my($result);
  1198.  
  1199.     if ((defined $argument) && ref($argument) &&
  1200.         (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
  1201.     {
  1202.         $result = $argument;
  1203.     }
  1204.     elsif ((defined $argument) && !(ref($argument)))
  1205.     {
  1206.         $result = $object->new($object->[1],$object->[2]);
  1207.         $result->Bit_On($argument);
  1208.     }
  1209.     else
  1210.     {
  1211.         croak "Set::IntegerRange $name: wrong argument type";
  1212.     }
  1213.     if ((defined $flag) && $flag)
  1214.     {
  1215.         return( $result->Compare($object) );
  1216.     }
  1217.     else
  1218.     {
  1219.         return( $object->Compare($result) );
  1220.     }
  1221. }
  1222.  
  1223. sub _clone
  1224. {
  1225.     my($object,$argument,$flag) = @_;
  1226.     my($result);
  1227.  
  1228.     $result = $object->new($object->[1],$object->[2]);
  1229.     $result->Copy($object);
  1230.     return($result);
  1231. }
  1232.  
  1233. sub _trace
  1234. {
  1235.     my($text,$object,$argument,$flag) = @_;
  1236.  
  1237.     unless (defined $object)   { $object   = 'undef'; };
  1238.     unless (defined $argument) { $argument = 'undef'; };
  1239.     unless (defined $flag)     { $flag     = 'undef'; };
  1240.     if (ref($object))   { $object   = ref($object);   }
  1241.     if (ref($argument)) { $argument = ref($argument); }
  1242.     print "$text: \$obj='$object' \$arg='$argument' \$flag='$flag'\n";
  1243. }
  1244.  
  1245. 1;
  1246.  
  1247. __END__
  1248.  
  1249. =head1 NAME
  1250.  
  1251. Set::IntegerRange - Sets of Integers
  1252.  
  1253. Easy manipulation of sets of integers (arbitrary intervals)
  1254.  
  1255. =head1 SYNOPSIS
  1256.  
  1257. =head2 METHODS
  1258.  
  1259.   Version
  1260.       $version = $Set::IntegerRange::VERSION;
  1261.  
  1262.   new
  1263.       $set = new Set::IntegerRange($lower,$upper);
  1264.       $set = Set::IntegerRange->new($lower,$upper);
  1265.       $set = $any_set->new($lower,$upper);
  1266.  
  1267.   Resize
  1268.       $set->Resize($lower,$upper);
  1269.  
  1270.   Size
  1271.       ($lower,$upper) = $set->Size();
  1272.  
  1273.   Empty
  1274.       $set->Empty();
  1275.  
  1276.   Fill
  1277.       $set->Fill();
  1278.  
  1279.   Flip
  1280.       $set->Flip();
  1281.  
  1282.   Interval_Empty
  1283.       $set->Interval_Empty($lower,$upper);
  1284.       $set->Empty_Interval($lower,$upper); # (deprecated)
  1285.  
  1286.   Interval_Fill
  1287.       $set->Interval_Fill($lower,$upper);
  1288.       $set->Fill_Interval($lower,$upper);  # (deprecated)
  1289.  
  1290.   Interval_Flip
  1291.       $set->Interval_Flip($lower,$upper);
  1292.       $set->Flip_Interval($lower,$upper);  # (deprecated)
  1293.  
  1294.   Interval_Scan_inc
  1295.       while (($min,$max) = $set->Interval_Scan_inc($start))
  1296.  
  1297.   Interval_Scan_dec
  1298.       while (($min,$max) = $set->Interval_Scan_dec($start))
  1299.  
  1300.   Bit_Off
  1301.       $set->Bit_Off($index);
  1302.       $set->Delete($index);                # (deprecated)
  1303.  
  1304.   Bit_On
  1305.       $set->Bit_On($index);
  1306.       $set->Insert($index);                # (deprecated)
  1307.  
  1308.   bit_flip
  1309.       $bit = $set->bit_flip($index);
  1310.       if ($set->bit_flip($index))
  1311.       $bit = $set->flip($index);           # (deprecated)
  1312.       if ($set->flip($index))              # (deprecated)
  1313.  
  1314.   bit_test
  1315.       $bit = $set->bit_test($index);
  1316.       if ($set->bit_test($index))
  1317.       $bit = $set->contains($index);
  1318.       if ($set->contains($index))
  1319.       $bit = $set->in($index);             # (deprecated)
  1320.       if ($set->in($index))                # (deprecated)
  1321.  
  1322.   Norm
  1323.       $norm = $set->Norm();
  1324.  
  1325.   Min
  1326.       $min = $set->Min();
  1327.  
  1328.   Max
  1329.       $max = $set->Max();
  1330.  
  1331.   Union
  1332.       $set1->Union($set2,$set3);           # in-place is possible!
  1333.  
  1334.   Intersection
  1335.       $set1->Intersection($set2,$set3);    # in-place is possible!
  1336.  
  1337.   Difference
  1338.       $set1->Difference($set2,$set3);      # in-place is possible!
  1339.  
  1340.   ExclusiveOr
  1341.       $set1->ExclusiveOr($set2,$set3);     # in-place is possible!
  1342.  
  1343.   Complement
  1344.       $set1->Complement($set2);            # in-place is possible!
  1345.  
  1346.   is_empty
  1347.       if ($set->is_empty())
  1348.  
  1349.   is_full
  1350.       if ($set->is_full())
  1351.  
  1352.   equal
  1353.       if ($set1->equal($set2))
  1354.  
  1355.   subset
  1356.       if ($set1->subset($set2))
  1357.       if ($set1->inclusion($set2))         # (deprecated)
  1358.  
  1359.   lexorder
  1360.       if ($set1->lexorder($set2))
  1361.  
  1362.   Compare
  1363.       $cmp = $set1->Compare($set2);
  1364.  
  1365.   Copy
  1366.       $set1->Copy($set2);
  1367.  
  1368.   Shadow
  1369.       $other_set = $some_set->Shadow();
  1370.  
  1371.   Clone
  1372.       $twin_set = $some_set->Clone();
  1373.  
  1374.   to_ASCII
  1375.       $string = $set->to_ASCII();          # e.g., "-8..-5,-1..2,4,6..9"
  1376.  
  1377.   from_ASCII
  1378.       eval { $set->from_ASCII($string); };
  1379.  
  1380.   to_String
  1381.       $string = $set->to_String();         # e.g., "0007AF1E"
  1382.  
  1383.   from_String
  1384.       eval { $set->from_String($string); };
  1385.  
  1386.   BitVector
  1387.       $set->BitVector->any_Bit_Vector_method();
  1388.  
  1389. =head2 OVERLOADED OPERATORS
  1390.  
  1391.  
  1392.   Emptyness
  1393.       if ($set) # if not empty
  1394.       if (! $set) # if empty
  1395.       unless ($set) # if empty
  1396.  
  1397.   Equality
  1398.       if ($set1 == $set2)
  1399.       if ($set1 != $set2)
  1400.       if ($set == $index)
  1401.       if ($set != $index)
  1402.  
  1403.   Lexical Comparison
  1404.       $cmp = $set1 cmp $set2;
  1405.       if ($set1 lt $set2)
  1406.       if ($set1 le $set2)
  1407.       if ($set1 gt $set2)
  1408.       if ($set1 ge $set2)
  1409.       if ($set1 eq $set2)
  1410.       if ($set1 ne $set2)
  1411.       $cmp = $set cmp $index;
  1412.       if ($set lt $index)
  1413.       if ($set le $index)
  1414.       if ($set gt $index)
  1415.       if ($set ge $index)
  1416.       if ($set eq $index)
  1417.       if ($set ne $index)
  1418.  
  1419.   String Conversion
  1420.       $string = "$set";
  1421.       print "\$set = '$set'\n";
  1422.  
  1423.   Union
  1424.       $set1 = $set2 + $set3;
  1425.       $set1 += $set2;
  1426.       $set1 = $set2 | $set3;
  1427.       $set1 |= $set2;
  1428.       $set1 = $set2 + $index;
  1429.       $set += $index;
  1430.       $set1 = $set2 | $index;
  1431.       $set |= $index;
  1432.  
  1433.   Intersection
  1434.       $set1 = $set2 * $set3;
  1435.       $set1 *= $set2;
  1436.       $set1 = $set2 & $set3;
  1437.       $set1 &= $set2;
  1438.       $set1 = $set2 * $index;
  1439.       $set *= $index;
  1440.       $set1 = $set2 & $index;
  1441.       $set &= $index;
  1442.  
  1443.   Difference
  1444.       $set1 = $set2 - $set3;
  1445.       $set1 -= $set2;
  1446.       $set1 = $set2 - $set1;
  1447.       $set1 = $set2 - $index;
  1448.       $set1 = $index - $set2;
  1449.       $set -= $index;
  1450.  
  1451.   ExclusiveOr
  1452.       $set1 = $set2 ^ $set3;
  1453.       $set1 ^= $set2;
  1454.       $set1 = $set2 ^ $index;
  1455.       $set ^= $index;
  1456.  
  1457.   Complement
  1458.       $set1 = -$set2;
  1459.       $set1 = ~$set2;
  1460.       $set = -$set;
  1461.       $set = ~$set;
  1462.  
  1463.   Subset Relationship
  1464.       if ($set1 <= $set2)
  1465.  
  1466.   True Subset Relationship
  1467.       if ($set1 < $set2)
  1468.  
  1469.   Superset Relationship
  1470.       if ($set1 >= $set2)
  1471.  
  1472.   True Superset Relationship
  1473.       if ($set1 > $set2)
  1474.  
  1475.   Norm
  1476.       $norm = abs($set);
  1477.  
  1478. =head1 DESCRIPTION
  1479.  
  1480. This class lets you dynamically create sets of arbitrary intervals of
  1481. integers and perform all the basic operations for sets on them (for a
  1482. list of available methods and operators, see above).
  1483.  
  1484. See L<Bit::Vector(3)> for more details!
  1485.  
  1486. =head1 SEE ALSO
  1487.  
  1488. Bit::Vector(3), Set::IntegerFast(3), Math::MatrixBool(3),
  1489. Math::MatrixReal(3), DFA::Kleene(3), Math::Kleene(3),
  1490. Graph::Kruskal(3).
  1491.  
  1492. =head1 VERSION
  1493.  
  1494. This man page documents "Set::IntegerRange" version 4.2.
  1495.  
  1496. =head1 AUTHOR
  1497.  
  1498. Steffen Beyer <sb@sdm.de>.
  1499.  
  1500. =head1 COPYRIGHT
  1501.  
  1502. Copyright (c) 1996, 1997 by Steffen Beyer. All rights reserved.
  1503.  
  1504. =head1 LICENSE
  1505.  
  1506. This package is free software; you can redistribute it and/or
  1507. modify it under the same terms as Perl itself.
  1508.  
  1509.